
#ifndef _NEBULA_SDK__SERVICE_H_
#define _NEBULA_SDK__SERVICE_H_

#include "Queue.h"
#include "ServiceAgent.h"
#include "Task.h"
#include "Utility/ErrorCode.h"

namespace nebula { namespace sdk {

class IService
{
public:
	virtual ~IService() {}

public:
	virtual NEBULA_ERROR_CODE Initialize (const char*, IServiceAgent*) = 0;
	virtual NEBULA_ERROR_CODE Start      () = 0;
	virtual void              Stop       () = 0;
	virtual void              Finalize   () = 0;

public:
	//All these state transferring handler functions should not blocking 
	// since the state transferring procedures are exclusive
	virtual void OnConfiguring    () = 0;
	virtual void OnConfigured     () = 0;
	virtual void OnAboutToPausing () = 0;
	virtual void OnPausing        () = 0;
	virtual void OnResuming       () = 0;
	virtual void OnAboutToRetiring() = 0;
	virtual void OnRetiring       () = 0;
	virtual void OnRetired        () = 0;

public:
	//Check whether service is overload or underload.
	//
	//The framework will change the state of a service to ABOUT-TO-PAUSING if
	// the service is overload (and change to PAUSING if it's still overload
	// in some couple seconds).  Tasks will not be transferred to the service
	// if it's in PAUSING state.
	//
	//The service can implement these API by comparing its queues' traffic
	// with queues' current capacity.
	//
	//Note to prevent the service swings from PAUSING and WORKING state
	// frequently, a service should not use a same threshold to judge the
	// overload/underload status.  E.g.: a service becomes overload when the
	// sum of its queues' size is larger than 10000, and becomes underload
	// when the sum is less than 8000 (not 10000).
	virtual bool IsOverload  () = 0;
	virtual bool IsUnderload () = 0;
};

}} // end of nebula::sdk

#endif // _NEBULA_SDK__SERVICE_H_

